package com.taoist_awei.blog.api;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.taoist_awei.blog.core.*;
import com.taoist_awei.blog.exception.InvalidRequestException;
import com.taoist_awei.blog.exception.UnKnownException;
import com.taoist_awei.blog.exception.UserNotFoundException;
import com.taoist_awei.blog.infrastructure.data.UserData;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import java.util.Optional;

@RestController
@RequestMapping("/user")
public class UserApi {
    private EncryptService encryptService;
    private UserRepository userRepository;
    private JwtService jwtService;
    private UserLoginService loginService;


    @Autowired
    public UserApi(EncryptService encryptService,
                   UserRepository userRepository,
                   JwtService jwtService,
                   UserLoginService loginService) {
        this.encryptService = encryptService;
        this.userRepository = userRepository;
        this.jwtService = jwtService;
        this.loginService = loginService;
    }

    @PostMapping(path = "/login")
    public ResponseEntity<?> login(@Valid @RequestBody LoginParam loginParam,
                                   BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new InvalidRequestException(bindingResult);
        }
        Optional<UserEntity> userByEmail = userRepository.findUserByEmail(loginParam.getEmail());
        if (userByEmail.isPresent()) {
            UserEntity userEntity = userByEmail.get();
            if (encryptService.check(userEntity.getPassword(), loginParam.getPassword())) {
                String token = jwtService.toToken(userEntity);
                UserData userData = new UserData(userEntity);
                HttpResult result = new HttpResult.HttpResultBuilder()
                        .statusCode(200)
                        .message("请求成功")
                        .data(userData)
                        .token(token)
                        .build();
                return ResponseEntity.ok(result);
            }
        } else {
            HttpResult result = new HttpResult.HttpResultBuilder()
                    .data(loginParam)
                    .message("用户名或密码错误")
                    .statusCode(400)
                    .build();
            return ResponseEntity.ok(result);
        }
        throw new UnKnownException();
    }

    @GetMapping("/logout/{email}")
    public ResponseEntity<?> logout(@PathVariable String email) {
        userRepository.findUserByEmail(email).ifPresent(userEntity -> {
            loginService.logout(userEntity.getUserId());
        });
        HttpResult result = new HttpResult.HttpResultBuilder()
                .statusCode(200)
                .message("登出成功")
                .data(email)
                .build();
        return ResponseEntity.ok(result);
    }

    @PostMapping("/update")
    public ResponseEntity<?> updateUser(@Valid @RequestBody UpdateParam updateParam,
                                        BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            throw new InvalidRequestException(bindingResult);
        }
        if(userRepository.findUserByEmail(updateParam.getEmail()).isPresent()) {
           UserEntity userEntity = new UserEntity(updateParam.getUsername(), updateParam.getPassword(), null);
           userEntity.setIntroduce(updateParam.getIntroduce());
           userEntity.setLocation(updateParam.getLocation());
           userEntity.setUserImage(updateParam.getUserImage());
           userRepository.save(userEntity);
           HttpResult result = new HttpResult.HttpResultBuilder().ok(updateParam);
           return ResponseEntity.ok(result);
        }
        throw new UserNotFoundException();
    }

    @GetMapping("findByEmail/{email}")
    public ResponseEntity<?> findByEmail(@PathVariable("email") String email) {
        Optional<UserEntity> userByEmail = userRepository.findUserByEmail(email);
        if (userByEmail.isPresent()) {
            UserData userData = new UserData(userByEmail.get());
            HttpResult result = new HttpResult.HttpResultBuilder().ok(userData);
            return ResponseEntity.ok(result);
        } else {
            throw new UserNotFoundException();
        }
    }
}


@Data
class LoginParam {

    @NotEmpty(message = "邮箱不能为空")
    @Email(message = "邮箱格式错误")
    @JsonProperty("email")
    private String email;

    @NotEmpty(message = "密码不能为空")
    @JsonProperty("password")
    private String password;
}

@Data
class UpdateParam {
    @JsonProperty("email")
    @NotEmpty(message = "邮箱不能为空")
    private String email;

    @JsonProperty("username")
    private String username;

    @JsonProperty("password")
    private String password;

    @JsonProperty("introduce")
    private String introduce;

    @JsonProperty("location")
    private String location;

    @JsonProperty("userImage")
    private String userImage;
}
